{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "32fd98cb-f09e-443f-8d28-a8ea5d6220ef",
   "metadata": {},
   "source": [
    "## Using a tool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "305645ad-cca2-4cd9-a8a8-160d2fac1369",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.tools import WikipediaQueryRun\n",
    "from langchain_community.utilities import WikipediaAPIWrapper\n",
    "\n",
    "api_wrapper = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=100)\n",
    "tool = WikipediaQueryRun(api_wrapper=api_wrapper)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "74ceb0f4-ae64-490b-b3cd-b241ede2da5b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'wikipedia'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tool.name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "4643c85e-24ab-49e8-b060-8f0388c1360d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'A wrapper around Wikipedia. Useful for when you need to answer general questions about people, places, companies, facts, historical events, or other subjects. Input should be a search query.'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tool.description"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "40b13fa4-64f0-4406-8530-f823a9aa9c47",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'query': {'title': 'Query', 'type': 'string'}}"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tool.args"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "530724cb-a851-4daf-aef0-bc3ee7326902",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tool.return_direct"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "e4296277-da67-405c-a3cc-18a3f07bedd6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Page: LangChain\\nSummary: LangChain is a framework designed to simplify the creation of applications '"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tool.run({\"query\": \"langchain\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "47c06e60-e4f7-4fd0-82c4-4f9936290225",
   "metadata": {},
   "source": [
    "## Custom tools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "cb85b3ce-422d-4f5f-bd8c-eed11e4b47ea",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'LangChain'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain.tools import tool\n",
    "\n",
    "\n",
    "@tool\n",
    "def search(query: str) -> str:\n",
    "    \"\"\"Look up things online.\"\"\"\n",
    "    return \"LangChain\"\n",
    "\n",
    "search(\"What's the best application framework for LLMs?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "382f83a3-d3e9-42cb-b231-700a09accbcc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'LangChain'"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain.pydantic_v1 import BaseModel, Field\n",
    "\n",
    "class SearchInput(BaseModel):\n",
    "    query: str = Field(description=\"should be a search query\")\n",
    "\n",
    "@tool(\"search-tool\", args_schema=SearchInput, return_direct=True)\n",
    "def search(query: str) -> str:\n",
    "    \"\"\"Look up things online.\"\"\"\n",
    "    return \"LangChain\"\n",
    "\n",
    "search(\"How do we implement LLM apps?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "b2a79105-b3c1-404d-8692-b60aa73e602f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'LangChain'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from typing import Optional, Type\n",
    "from langchain.tools import BaseTool\n",
    "from langchain.callbacks.manager import (\n",
    "    AsyncCallbackManagerForToolRun,\n",
    "    CallbackManagerForToolRun,\n",
    ")\n",
    "\n",
    "class SearchInput(BaseModel):\n",
    "    query: str = Field(description=\"should be a search query\")\n",
    "\n",
    "class CustomSearchTool(BaseTool):\n",
    "    name = \"custom_search\"\n",
    "    description = \"useful for when you need to answer questions about current events\"\n",
    "    args_schema: Type[BaseModel] = SearchInput\n",
    "\n",
    "    def _run(self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None) -> str:\n",
    "        \"\"\"Use the tool.\"\"\"\n",
    "        return \"LangChain\"\n",
    "\n",
    "    async def _arun(self, query: str, run_manager: Optional[AsyncCallbackManagerForToolRun] = None) -> str:\n",
    "        \"\"\"Use the tool asynchronously.\"\"\"\n",
    "        raise NotImplementedError(\"custom_search does not support async\")\n",
    "\n",
    "search = CustomSearchTool()\n",
    "search(\"What's the most popular tool for writing LLM apps?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "330f1fd7-e95b-4663-be78-7c62e9aa7714",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'LangChain'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain.tools import StructuredTool\n",
    "\n",
    "def search_function(query: str):\n",
    "    return \"LangChain\"\n",
    "\n",
    "search = StructuredTool.from_function(\n",
    "    func=search_function,\n",
    "    name=\"Search\",\n",
    "    description=\"useful for when you need to answer questions about current events\",\n",
    ")\n",
    "search(\"Which framework has hundreds of integrations to use with LLMs?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f770e05f-27a1-402a-b0d8-d80bc61a3836",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000000000"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    " class CalculatorInput(BaseModel):\n",
    "    a: int = Field(description=\"first number\")\n",
    "    b: int = Field(description=\"second number\")\n",
    "\n",
    "def multiply(a: int, b: int) -> int:\n",
    "    \"\"\"Multiply two numbers.\"\"\"\n",
    "    return a * b\n",
    "\n",
    "calculator = StructuredTool.from_function(\n",
    "    func=multiply,\n",
    "    name=\"Calculator\",\n",
    "    description=\"multiply numbers\",\n",
    "    args_schema=CalculatorInput,\n",
    "    return_direct=True,\n",
    ") \n",
    "\n",
    "calculator.run(dict(a=1_000_000_000, b=2))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c9bed00-e17a-411d-bea8-fc7f90f404df",
   "metadata": {},
   "source": [
    "## Error handling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9b2bdfea-4019-4253-a385-f9cf04901162",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'The search tool is not available.'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_core.tools import ToolException\n",
    "\n",
    "def search_tool(s: str):\n",
    "    raise ToolException(\"The search tool is not available.\")\n",
    "\n",
    "search = StructuredTool.from_function(\n",
    "    func=search_tool,\n",
    "    name=\"Search_tool\",\n",
    "    description=\"A bad tool\",\n",
    "    handle_tool_error=True,\n",
    ")\n",
    "search(\"Search the internet and compress everything into a paragraph!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2c8a1483-c759-4880-8ade-8bd34464536f",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
